#lang racket

(define (count-change amount)
  (define (cc amount kinds-of-coins)
    (cond ((= amount 0) 1)
          ((or (< amount 0) (= kinds-of-coins 0)) 0)
          (else (+ (cc amount (- kinds-of-coins 1))
                   (cc (- amount (values-of-coins kinds-of-coins))
                       kinds-of-coins)))))
;尝试改成tail call的形式，然而下面这个并不是:(
;    (define (cc-iter total amount kinds-of-coins)
;    (cond ((= amount 0) (+ total 1))
;          ((or (< amount 0) (= kinds-of-coins 0)) total)
;          (else (+ total
;                   (cc-iter total amount (- kinds-of-coins 1))
;                   (cc-iter total
;                            (- amount (values-of-coins kinds-of-coins))
;                            kinds-of-coins)))))
  (define (values-of-coins kinds-of-coins)
    (cond ((= kinds-of-coins 1) 1)
          ((= kinds-of-coins 2) 5)
          ((= kinds-of-coins 3) 10)
          ((= kinds-of-coins 4) 25)
          ((= kinds-of-coins 5) 50)))
  (cc-iter 0 amount 5))

(count-change 100)
